package br.com.usapre.faces;

import java.io.File;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.List;

import javax.faces.context.FacesContext;

import org.jrimum.bopepo.BancosSuportados;
import org.jrimum.bopepo.Boleto;
import org.jrimum.bopepo.view.BoletoViewer;
import org.jrimum.domkee.comum.pessoa.endereco.CEP;
import org.jrimum.domkee.comum.pessoa.endereco.UnidadeFederativa;
import org.jrimum.domkee.financeiro.banco.febraban.Agencia;
import org.jrimum.domkee.financeiro.banco.febraban.Carteira;
import org.jrimum.domkee.financeiro.banco.febraban.Cedente;
import org.jrimum.domkee.financeiro.banco.febraban.ContaBancaria;
import org.jrimum.domkee.financeiro.banco.febraban.NumeroDaConta;
import org.jrimum.domkee.financeiro.banco.febraban.Sacado;
import org.jrimum.domkee.financeiro.banco.febraban.TipoDeTitulo;
import org.jrimum.domkee.financeiro.banco.febraban.Titulo;
import org.jrimum.domkee.financeiro.banco.febraban.Titulo.EnumAceite;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import br.com.business.CartaoBusiness;
import br.com.business.EnderecoBusiness;
import br.com.businesssql.LimiteValorBoletoBusiness;
import br.com.data.Bairro;
import br.com.data.Cartao;
import br.com.data.Cidade;
import br.com.data.Endereco;
import br.com.data.Logradouro;
import br.com.data.Uf;
import br.com.datasql.LimiteValorBoleto;
import br.com.login.faces.SessionUsaPreBean;
import br.com.utilidades.faces.SimpleMessageBean;

/**
 * @version 1.0.0
 * @since Fevereiro,28 2013
 * @author Eduardo Francisco Barbosa
 */
@Component
@Scope("view")
public class RecarregueBean extends SimpleMessageBean implements Serializable {

    private static final long serialVersionUID = 2556502296164074235L;

    private SessionUsaPreBean sessionUsaPreBean;

    private EnderecoBusiness enderecoBusinessImpl;
    private CartaoBusiness cartaoBusinessImpl;
    private LimiteValorBoletoBusiness limiteValorBoletoBusinessImpl;

    private Float valor;

    private Integer codigoConvenio = 531;

    private Double valorMinimo;
    private Double valorMaximo;

    /**
     * Construtor
     */
    @Autowired
    public RecarregueBean(SessionUsaPreBean sessionUsaPreBean, EnderecoBusiness enderecoBusinessImpl,
	    CartaoBusiness cartaoBusinessImpl, LimiteValorBoletoBusiness limiteValorBoletoBusinessImpl) {

	this.sessionUsaPreBean = sessionUsaPreBean;

	this.cartaoBusinessImpl = cartaoBusinessImpl;
	this.enderecoBusinessImpl = enderecoBusinessImpl;
	this.limiteValorBoletoBusinessImpl = limiteValorBoletoBusinessImpl;

	reset();
    }

    /**
     * reset
     */
    public void reset() {
	valor = 0f;
	LimiteValorBoleto limite = limiteValorBoletoBusinessImpl.buscarLimiteValorBoleto(codigoConvenio);
	valorMinimo = limite.getLimiteMin();
	valorMaximo = limite.getLimiteMax();
    }

    /**
     * metodo responsavel por gerar o boleto
     * 
     * gerarBoleto
     */
    public void gerarBoleto() {

	if (valor < valorMinimo) {

	    String msg = super.getMensagem("MN_valor_boleto_menor") + " " + valorMinimo + " reais. ";
	    enviaMensagem(msg, msg);

	} else {
	    if (valor > valorMaximo) {

		String msg = super.getMensagem("MN_valor_boleto_maior") + " " + valorMaximo + " reais. ";
		enviaMensagem(msg, msg);

	    } else {

		List<Cartao> cartoes = cartaoBusinessImpl.buscarCartoesAtivosPorUsuario(sessionUsaPreBean.getUsuario());

		if (cartoes.size() == 0) {
		    String msg = super.getMensagem("MN_nao_existe_cartao_liberado") + " "
			    + sessionUsaPreBean.getUsuario().getNome();
		    enviaMensagem(msg, msg);
		} else {

		    if (cartoes.size() > 1) {
			String msg = super.getMensagem("MN_erro_conta");
			enviaMensagem(msg, msg);
		    } else {

			Cartao cartao = cartoes.get(0);

			Cedente cedente = new Cedente("Nacional S/A Administradora de Cartões de Crédito",
				"08.011.683/0001-94");
			Sacado sacado = new Sacado(sessionUsaPreBean.getUsuario().getNome(), sessionUsaPreBean
				.getUsuario().getCnpjCpf());
			Endereco endereco = enderecoBusinessImpl.buscarEnderecoPorUsuario(sessionUsaPreBean
				.getUsuario());

			if (endereco == null) {

			} else {
			    Logradouro logradouro = endereco.getLogradouro();
			    Bairro bairro = logradouro.getBairro();
			    Cidade cidade = bairro.getCidade();
			    Uf uf = cidade.getUf();

			    // Informando o endereço do sacado.
			    org.jrimum.domkee.comum.pessoa.endereco.Endereco enderecoSac = new org.jrimum.domkee.comum.pessoa.endereco.Endereco();

			    String cepSemFormatacao = logradouro.getCep().toString();
			    while (cepSemFormatacao.length() < 9) {
				cepSemFormatacao = "0" + cepSemFormatacao;
			    }
			    String cepString = cepSemFormatacao.substring(0, 5) + "-"
				    + cepSemFormatacao.substring(6, 9);

			    enderecoSac.setUF(getUnidadeFederativa(uf));
			    enderecoSac.setLocalidade(cidade.getNome());
			    enderecoSac.setCep(new CEP(cepString));
			    enderecoSac.setBairro(bairro.getNome());
			    enderecoSac.setLogradouro(logradouro.getNome());
			    enderecoSac.setNumero(endereco.getNumero());
			    sacado.addEndereco(enderecoSac);
			}

			ContaBancaria contaBancaria = new ContaBancaria(BancosSuportados.BANCO_BRADESCO.create());
			contaBancaria.setNumeroDaConta(new NumeroDaConta(14530, "0"));
			contaBancaria.setCarteira(new Carteira(6));
			contaBancaria.setAgencia(new Agencia(3458, "4"));

			Titulo titulo = new Titulo(contaBancaria, sacado, cedente);
			// titulo.setNumeroDoDocumento("1988935");
			// titulo.setNossoNumero("1988935");
			// titulo.setDigitoDoNossoNumero("3");

			titulo.setNumeroDoDocumento(cartao.getNossoNumero());
			titulo.setNossoNumero(cartao.getNossoNumero());
			titulo.setDigitoDoNossoNumero(cartao.getDigitoNossoNumero().toString());
			titulo.setValor(BigDecimal.ZERO);
			titulo.setDataDoDocumento(new Date());
			titulo.setDataDoVencimento(org.jrimum.bopepo.FatorDeVencimento.toDate(0));
			titulo.setAceite(EnumAceite.N);
			titulo.setTipoDeDocumento(TipoDeTitulo.DM_DUPLICATA_MERCANTIL);
			titulo.setDesconto(BigDecimal.ZERO);
			titulo.setDeducao(BigDecimal.ZERO);
			titulo.setMora(BigDecimal.ZERO);
			titulo.setAcrecimo(BigDecimal.ZERO);
			titulo.setValorCobrado(BigDecimal.ZERO);

			Boleto boleto = new Boleto(titulo);

			boleto.setLocalPagamento("PREFERENCIALMENTE NAS AGENCIAS DO BRADESCO.");
			boleto.setInstrucaoAoSacado("Boleto de Recarga do seu USACARD PRÉ");
			boleto.setInstrucao1(" ");
			boleto.setInstrucao2(" ");
			boleto.setInstrucao3(" ");
			boleto.setInstrucao4(" ");
			boleto.setInstrucao5(" ");
			boleto.setInstrucao6(" ");
			boleto.setInstrucao7(" ");
			boleto.setInstrucao8(" ");

			boleto.addTextosExtras("txtFcDataVencimento", "CONTRA-APRESENTAÇÃO");
			boleto.addTextosExtras("txtRsDataVencimento", "CONTRA-APRESENTAÇÃO");

			NumberFormat f = new DecimalFormat("0.00");

			boleto.addTextosExtras("txtRsValor", "R$ " + f.format(valor));
			boleto.addTextosExtras("txtRsValorDocumento", "R$ " + f.format(valor));
			boleto.addTextosExtras("txtRsDescontoAbatimento", " ");
			boleto.addTextosExtras("txtRsOutraDeducao", " ");
			boleto.addTextosExtras("txtRsMoraMulta", " ");
			boleto.addTextosExtras("txtRsOutroAcrescimo", " ");
			boleto.addTextosExtras("txtRsValorCobrado", " ");

			boleto.addTextosExtras("txtFcValor", "R$ " + f.format(valor));
			boleto.addTextosExtras("txtFcValorDocumento", "R$ " + f.format(valor));
			boleto.addTextosExtras("txtFcDescontoAbatimento", " ");
			boleto.addTextosExtras("txtFcOutraDeducao", " ");
			boleto.addTextosExtras("txtFcMoraMulta", " ");
			boleto.addTextosExtras("txtFcOutroAcrescimo", " ");
			boleto.addTextosExtras("txtFcValorCobrado", " ");

			BoletoViewer boletoViewer = new BoletoViewer(boleto);
			File arquivoPdf = boletoViewer.getPdfAsFile("MeuPrimeiroBoleto.pdf");

			OperacoesArquivos.downloadFile(arquivoPdf, "pdf", FacesContext.getCurrentInstance());

		    }

		}

	    }

	}

    }

    /**
     * getUnidadeFederativa
     * 
     * @param uf
     * 
     * @return
     */
    private UnidadeFederativa getUnidadeFederativa(Uf uf) {

	switch (uf.getId()) {
	case 1:
	    return UnidadeFederativa.AC;
	case 2:
	    return UnidadeFederativa.AL;
	case 3:
	    return UnidadeFederativa.AP;
	case 4:
	    return UnidadeFederativa.AM;
	case 5:
	    return UnidadeFederativa.BA;
	case 6:
	    return UnidadeFederativa.CE;
	case 7:
	    return UnidadeFederativa.DF;
	case 8:
	    return UnidadeFederativa.ES;
	case 9:
	    return UnidadeFederativa.GO;
	case 10:
	    return UnidadeFederativa.MA;
	case 11:
	    return UnidadeFederativa.MT;
	case 12:
	    return UnidadeFederativa.MS;
	case 13:
	    return UnidadeFederativa.MG;
	case 14:
	    return UnidadeFederativa.PA;
	case 15:
	    return UnidadeFederativa.PB;
	case 16:
	    return UnidadeFederativa.PR;
	case 17:
	    return UnidadeFederativa.PE;
	case 18:
	    return UnidadeFederativa.PI;
	case 19:
	    return UnidadeFederativa.RJ;
	case 20:
	    return UnidadeFederativa.RN;
	case 21:
	    return UnidadeFederativa.RS;
	case 22:
	    return UnidadeFederativa.RO;
	case 23:
	    return UnidadeFederativa.RR;
	case 24:
	    return UnidadeFederativa.SC;
	case 25:
	    return UnidadeFederativa.SE;
	case 26:
	    return UnidadeFederativa.SP;
	case 27:
	    return UnidadeFederativa.TO;

	default:
	    return UnidadeFederativa.DESCONHECIDO;
	}

    }

    // SETS AND GETS
    public Integer getCodigoConvenio() {
	return codigoConvenio;
    }

    public void setCodigoConvenio(Integer codigoConvenio) {
	this.codigoConvenio = codigoConvenio;
    }

    public Float getValor() {
	return valor;
    }

    public void setValor(Float valor) {
	this.valor = valor;
    }

    public LimiteValorBoletoBusiness getLimiteValorBoletoBusinessImpl() {
	return limiteValorBoletoBusinessImpl;
    }

    public void setLimiteValorBoletoBusinessImpl(LimiteValorBoletoBusiness limiteValorBoletoBusinessImpl) {
	this.limiteValorBoletoBusinessImpl = limiteValorBoletoBusinessImpl;
    }

}
